home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / BARNET / ARMTEX / SOURCES1 / !TeX / texmf / source / armTeX / lib / c / fontmap < prev    next >
Encoding:
Text File  |  1998-04-06  |  5.5 KB  |  213 lines

  1. /* fontmap.c: read a file for additional font names.
  2.  
  3. Copyright (C) 1993 Free Software Foundation, Inc.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include "c-pathmx.h"
  22. #include "fontmap.h"
  23.  
  24. /* Fontname mapping.  We use a straightforward hash table.  */
  25.  
  26. #define MAP_SIZE 199
  27.  
  28.  
  29. /* The hash function.  We go for simplicity here.  */
  30.  
  31. static unsigned
  32. map_hash (key)
  33.     char *key;
  34. {
  35.   unsigned n = 0;
  36.   
  37.   /* There are very few font names which are anagrams of each other (I
  38.      think), so no point in weighting the characters.  */
  39.   while (*key != 0)
  40.     n += *key++;
  41.   
  42.   n %= MAP_SIZE;
  43.   
  44.   return n;
  45. }
  46.  
  47. /* Look up STR in MAP.  Return the corresponding `value' or NULL.  */
  48.  
  49. static char *
  50. map_lookup_str (map, key)
  51.     map_type map;
  52.     char *key;
  53. {
  54.   map_element_type *p;
  55.   unsigned n = map_hash (key);
  56.   
  57.   for (p = map[n]; p != NULL; p = p->next)
  58.     if (STREQ (key, p->key))
  59.       return p->value;
  60.   
  61.   return NULL;
  62. }
  63.  
  64.  
  65. /* Look up KEY in MAP; if it's not found, remove any suffix from KEY and
  66.    try again.  */
  67.  
  68. char *
  69. map_lookup (map, key)
  70.     map_type map;
  71.     char *key;
  72. {
  73.   extern string extend_filename ();
  74.   string suffix = find_suffix (key);
  75.   string ret = map_lookup_str (map, key);
  76.   
  77.   if (!ret)
  78.     {
  79.       /* OK, the original KEY didn't work.  Let's check for the KEY without
  80.          an extension -- perhaps they gave foobar.tfm, but the mapping only
  81.          defines `foobar'.  */
  82.       if (suffix)
  83.         {
  84.           string base_key = remove_suffix (key);
  85.           
  86.           ret = map_lookup_str (map, base_key);
  87.  
  88.           free (base_key);
  89.         }
  90.     }
  91.  
  92.   /* Append the same suffix we took off, if necessary.  */
  93.   if (ret)
  94.     ret = extend_filename (ret, suffix);
  95.  
  96.   return ret;
  97. }
  98.  
  99. /* If KEY is not already in MAP, insert it and VALUE.  */
  100.  
  101. static void
  102. map_insert (map, key, value)
  103.     map_type map;
  104.     char *key;
  105.     char *value;
  106. {
  107.   unsigned n = map_hash (key);
  108.   map_element_type **p = &map[n];
  109.   map_element_type ***trailer = &p;
  110.  
  111.   while (*p != NULL && !STREQ (key, (*p)->key))
  112.     {
  113.        *p = (*p)->next;
  114.        trailer = &p;
  115.     }
  116.  
  117.   if (*p == NULL)
  118.     {
  119.       **trailer = XTALLOC (MAP_SIZE, map_element_type);
  120.       (**trailer)->key = xstrdup (key);
  121.       (**trailer)->value = xstrdup (value);
  122.       (**trailer)->next = NULL;
  123.     }
  124. }
  125.  
  126. /* Open and read the mapping file FILENAME, putting its entries into
  127.    MAP. Comments begin with % and continue to the end of the line.  Each
  128.    line of the file defines an entry: the first word is the real
  129.    filename (e.g., `ptmr'), the second word is the alias (e.g.,
  130.    `Times-Roman'), and any subsequent words are ignored.  .tfm is added
  131.    if either the filename or the alias have no extension.  This is the
  132.    same order as in Dvips' psfonts.map; unfortunately, we can't have TeX
  133.    read that same file, since most of the real filenames start with an
  134.    `r', because of the virtual fonts Dvips uses.  */
  135.  
  136. static void
  137. map_file_parse (map, map_filename)
  138.     map_type map;
  139.     char *map_filename;
  140. {
  141.   extern FILE *xfopen ();    /* In xfopen.c.  */
  142.   extern char *read_line ();    /* In line.c.  */
  143.   char *l;
  144.   unsigned map_lineno = 0;
  145.   FILE *f = xfopen (map_filename, FOPEN_R_MODE);
  146.   
  147.   while ((l = read_line (f)) != NULL)
  148.     {
  149.       string filename;
  150.       string comment_loc = strrchr (l, '%');
  151.       
  152.       map_lineno++;
  153.       
  154.       /* Ignore anything after a %.  */
  155.       if (comment_loc)
  156.         *comment_loc = 0;
  157.       
  158.       /* If we don't have any filename, that's ok, the line is blank.  */
  159.       filename = strtok (l, " \t");
  160.       if (filename)
  161.         {
  162.           string alias = strtok (NULL, " \t");
  163.           
  164.           /* But if we have a filename and no alias, something's wrong.  */
  165.           if (alias == NULL || *alias == 0)
  166.             fprintf (stderr, "%s:%u: Alias missing for filename `%s'.\n",
  167.                      map_filename, map_lineno, filename);
  168.           else
  169.             {
  170.               /* We've got everything.  Insert the new entry.  */
  171.               map_insert (map, alias, filename);
  172.             }
  173.         }
  174.       
  175.       free (l);
  176.     }
  177.   
  178.   xfclose (f, map_filename);
  179. }
  180.  
  181.  
  182. /* Look for the file `texfonts.map' in each of the directories in
  183.    DIR_LIST.  Entries in earlier files override later files.  */
  184.  
  185. map_type
  186. map_create (dir_list)
  187.     string *dir_list;
  188. {
  189.   map_type map = (map_type) xcalloc (MAP_SIZE, sizeof (map_element_type *));
  190.   
  191.   while (*dir_list)
  192.     {
  193.       char filename[PATH_MAX];
  194.       
  195.       /* We don't bother with the filename truncation that `readable' in
  196.          `pathsrch.c' does, since we ourselves are giving the filename,
  197.          and I don't think it's worth worrying about too-long
  198.          intermediate directory names in the path.  */
  199.       strcpy (filename, *dir_list);
  200.       strcat (filename, "texfonts.map");
  201.       
  202. #ifdef RISCOS
  203.       if (riscos_readaccess(filename))
  204. #else
  205.       if (access (filename, R_OK) == 0)
  206. #endif
  207.         map_file_parse (map, filename);
  208.       
  209.       dir_list++;
  210.     }
  211.   return map;
  212. }
  213.